package com.rpoonolly.simplegame.worldGrid;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.rpoonolly.simplegame.core.aabb.AABBEntity;

public class WorldGrid implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private final int originX, originY;
	private final int gridCellWidth, gridCellHeight;
	private Map<GridCoordinate, WorldGridTile> grid;
	
	public WorldGrid(int originX, int originY, int gridCellWidth, int gridCellHeight) {
		this.originX = originX;
		this.originY = originY;
		this.gridCellWidth = gridCellWidth;
		this.gridCellHeight = gridCellHeight;
		
		this.grid = new ConcurrentHashMap<GridCoordinate, WorldGridTile>();
	}
	
	public List<WorldGridTile> getCollidingTiles(AABBEntity entity) {
		int xleft = (int) Math.floor(((double) entity.getX()) / gridCellWidth);
		int xright = (int) Math.ceil(((double) entity.getX() + entity.getWidth()) / gridCellWidth);
		int ybottom = (int) Math.floor(((double) entity.getY()) / gridCellHeight);
		int ytop = (int) Math.ceil(((double) entity.getY() + entity.getHeight()) / gridCellHeight);

		List<WorldGridTile> coordinates = new LinkedList<WorldGridTile>();
		for(int x = xleft; x <= xright; x++)
			for(int y = ybottom; y <= ytop; y++)
				if (x == 0 && y == 0)
					coordinates.add(getTile(new GridCoordinate(x, y)));
				else
					coordinates.add(getTile(new GridCoordinate(x, y)));
		
		return coordinates;
	}
	
	public WorldGridTile getTile(GridCoordinate coordinate) {
		WorldGridTile tile = grid.get(coordinate);
		if (tile == null)
			tile = new WorldGridTile(coordinate, null);
		
		return tile;
	}
	
	public Collection<WorldGridTile> getSavedTiles() {
		return grid.values();
	}
	
	public void putTile(WorldGridTile tile) {
		grid.put(tile.getCoordinate(), tile);
	}

	public int getOriginX() {
		return originX;
	}

	public int getOriginY() {
		return originY;
	}

	public int getGridCellWidth() {
		return gridCellWidth;
	}

	public int getGridCellHeight() {
		return gridCellHeight;
	}
	
	@Override
	public String toString() {
		String resultString = "";
		
		for (GridCoordinate coord : grid.keySet())
			resultString += "coord:" + coord + "\ttile" + getTile(coord) + "\n\n";

//		for (WorldGridTile tile : grid.values())
//			resultString += tile + "\n\n";

		return resultString;
	}
}
